home *** CD-ROM | disk | FTP | other *** search
/ L' Effet Pommier 3 / L'Effet Pommier - Volume 03.iso / Programmation / Alpha ƒ / Tcl / UserCode / Text Filters / Unix / s2p
Text File  |  1994-03-07  |  14KB  |  754 lines

  1. $bin = '/usr/local/bin';
  2.  
  3. # $RCSfile: s2p.SH,v $$Revision: 4.0.1.1 $$Date: 91/06/07 12:19:18 $
  4. #
  5. # $Log:    s2p.SH,v $
  6. # Revision 4.0.1.1  91/06/07  12:19:18  lwall
  7. # patch4: s2p now handles embedded newlines better and optimizes common idioms
  8. # Revision 4.0  91/03/20  01:57:59  lwall
  9. # 4.0 baseline.
  10. #-----------------------------------------------------------------
  11. # modified 2/94 by Tom Pollard <pollard@chem.columbia.edu>
  12. #
  13. # This version operates without writing to disk or calling the 
  14. # C preprocessor, making it usable with the standalone version of
  15. # MacPerl.
  16. #-----------------------------------------------------------------
  17.  
  18. $indent = 4;
  19. $shiftwidth = 4;
  20. $l = '{'; $r = '}';
  21.  
  22. $BODY = "" ;
  23.  
  24. while ($ARGV[0] =~ /^-/) {
  25.     $_ = shift;
  26.   last if /^--/;
  27. #    if (/^-D/) {
  28. #    $debug++;
  29. #    open(BODY,'>-');
  30. #    next;
  31. #    }
  32.     if (/^-n/) {
  33.     $assumen++;
  34.     next;
  35.     }
  36.     if (/^-p/) {
  37.     $assumep++;
  38.     next;
  39.     }
  40.     die "I don't recognize this switch: $_\n";
  41. }
  42.  
  43. if (!$assumen && !$assumep) {
  44.     $BODY .= &q(<<'EOT');
  45. :    while ($ARGV[0] =~ /^-/) {
  46. :        $_ = shift;
  47. :      last if /^--/;
  48. :        if (/^-n/) {
  49. :        $nflag++;
  50. :        next;
  51. :        }
  52. :        die "I don't recognize this switch: $_\\n";
  53. :    }
  54. :    
  55. EOT
  56. }
  57.  
  58. $BODY .= &q(<<'EOT');
  59. :    #ifdef PRINTIT
  60. :    #ifdef ASSUMEP
  61. :    $printit++;
  62. :    #else
  63. :    $printit++ unless $nflag;
  64. :    #endif
  65. :    #endif
  66. :    <><>
  67. :    $\ = "\n";        # automatically add newline on print
  68. :    <><>
  69. :    #ifdef TOPLABEL
  70. :    LINE:
  71. :    while (chop($_ = <>)) {
  72. :    #else
  73. :    LINE:
  74. :    while (<>) {
  75. :        chop;
  76. :    #endif
  77. EOT
  78.  
  79. LINE:
  80. while (<>) {
  81.  
  82.     # Wipe out surrounding whitespace.
  83.  
  84.     s/[ \t]*(.*)\n$/$1/;
  85.  
  86.     # Perhaps it's a label/comment.
  87.  
  88.     if (/^:/) {
  89.     s/^:[ \t]*//;
  90.     $label = &make_label($_);
  91.     if ($. == 1) {
  92.         $toplabel = $label;
  93.         if (/^(top|(re)?start|redo|begin(ning)|again|input)$/i) {
  94.         $_ = <>;
  95.         redo LINE; # Never referenced, so delete it if not a comment.
  96.         }
  97.     }
  98.     $_ = "$label:";
  99.     if ($lastlinewaslabel++) {
  100.         $indent += 4;
  101.         $BODY .= &tab.";\n";
  102.         $indent -= 4;
  103.     }
  104.     if ($indent >= 2) {
  105.         $indent -= 2;
  106.         $indmod = 2;
  107.     }
  108.     next;
  109.     } else {
  110.     $lastlinewaslabel = '';
  111.     }
  112.  
  113.     # Look for one or two address clauses
  114.  
  115.     $addr1 = '';
  116.     $addr2 = '';
  117.     if (s/^([0-9]+)//) {
  118.     $addr1 = "$1";
  119.     $addr1 = "\$. == $addr1" unless /^,/;
  120.     }
  121.     elsif (s/^\$//) {
  122.     $addr1 = 'eof()';
  123.     }
  124.     elsif (s|^/||) {
  125.     $addr1 = &fetchpat('/');
  126.     }
  127.     if (s/^,//) {
  128.     if (s/^([0-9]+)//) {
  129.         $addr2 = "$1";
  130.     } elsif (s/^\$//) {
  131.         $addr2 = "eof()";
  132.     } elsif (s|^/||) {
  133.         $addr2 = &fetchpat('/');
  134.     } else {
  135.         &Die("Invalid second address at line $.\n");
  136.     }
  137.     $addr1 .= " .. $addr2";
  138.     }
  139.  
  140.     # Now we check for metacommands {, }, and ! and worry
  141.     # about indentation.
  142.  
  143.     s/^[ \t]+//;
  144.     # a { to keep vi happy
  145.     if ($_ eq '}') {
  146.     $indent -= 4;
  147.     next;
  148.     }
  149.     if (s/^!//) {
  150.     $if = 'unless';
  151.     $else = "$r else $l\n";
  152.     } else {
  153.     $if = 'if';
  154.     $else = '';
  155.     }
  156.     if (s/^{//) {    # a } to keep vi happy
  157.     $indmod = 4;
  158.     $redo = $_;
  159.     $_ = '';
  160.     $rmaybe = '';
  161.     } else {
  162.     $rmaybe = "\n$r";
  163.     if ($addr2 || $addr1) {
  164.         $space = ' ' x $shiftwidth;
  165.     } else {
  166.         $space = '';
  167.     }
  168.     $_ = &transmogrify();
  169.     }
  170.  
  171.     # See if we can optimize to modifier form.
  172.  
  173.     if ($addr1) {
  174.     if ($_ !~ /[\n{}]/ && $rmaybe && !$change &&
  175.       $_ !~ / if / && $_ !~ / unless /) {
  176.         s/;$/ $if $addr1;/;
  177.         $_ = substr($_,$shiftwidth,1000);
  178.     } else {
  179.         $_ = "$if ($addr1) $l\n$change$_$rmaybe";
  180.     }
  181.     $change = '';
  182.     next LINE;
  183.     }
  184. } continue {
  185.     @lines = split(/\n/,$_);
  186.     for (@lines) {
  187.     unless (s/^ *<<--//) {
  188.         $BODY .= &tab;
  189.     }
  190.     $BODY .= $_."\n";
  191.     }
  192.     $indent += $indmod;
  193.     $indmod = 0;
  194.     if ($redo) {
  195.     $_ = $redo;
  196.     $redo = '';
  197.     redo LINE;
  198.     }
  199. }
  200. if ($lastlinewaslabel++) {
  201.     $indent += 4;
  202.     $BODY .= &tab.";\n";
  203.     $indent -= 4;
  204. }
  205.  
  206. if ($appendseen || $tseen || !$assumen) {
  207.     $printit++ if $dseen || (!$assumen && !$assumep);
  208.     $BODY .= &q(<<'EOT');
  209. :    #ifdef SAWNEXT
  210. :    }
  211. :    continue {
  212. :    #endif
  213. :    #ifdef PRINTIT
  214. :    #ifdef DSEEN
  215. :    #ifdef ASSUMEP
  216. :        print if $printit++;
  217. :    #else
  218. :        if ($printit)
  219. :        { print; }
  220. :        else
  221. :        { $printit++ unless $nflag; }
  222. :    #endif
  223. :    #else
  224. :        print if $printit;
  225. :    #endif
  226. :    #else
  227. :        print;
  228. :    #endif
  229. :    #ifdef TSEEN
  230. :        $tflag = 0;
  231. :    #endif
  232. :    #ifdef APPENDSEEN
  233. :        if ($atext) { chop $atext; print $atext; $atext = ''; }
  234. :    #endif
  235. EOT
  236.  
  237. $BODY .= &q(<<'EOT');
  238. :    }
  239. EOT
  240. }
  241.  
  242. unless ($debug) {
  243.     
  244.     $HEAD = "\n";
  245.     $HEAD .= "#define PRINTIT\n"    if $printit;
  246.     $HEAD .= "#define APPENDSEEN\n"    if $appendseen;
  247.     $HEAD .= "#define TSEEN\n"    if $tseen;
  248.     $HEAD .= "#define DSEEN\n"    if $dseen;
  249.     $HEAD .= "#define ASSUMEN\n"    if $assumen;
  250.     $HEAD .= "#define ASSUMEP\n"    if $assumep;
  251.     $HEAD .= "#define TOPLABEL\n"    if $toplabel;
  252.     $HEAD .= "#define SAWNEXT\n"    if $sawnext;
  253.  
  254.     if ($opens) {$HEAD .= "$opens\n";}
  255.  
  256.     @LINES = split(/^/,$HEAD.$BODY) ;    
  257.     
  258. #
  259. #  A very simple substitute for the C preprocessor
  260. #
  261. #  This code only interprets #define, #ifdef, #else, and #endif.
  262. #
  263. #  It can be used to process the output of the s2p (sed-to-perl) script.
  264. #
  265. #   2/19/94 : by Tom Pollard <pollard@chem.columbia.edu>
  266. #
  267.     $printit = 1;
  268.     $defs{"EMPTY"} = 0;
  269.  
  270.     foreach (@LINES) {
  271.      if (/^#define\s+(\w+)/) { 
  272.         $defs{$1} = $1 ; 
  273.         }
  274.      elsif (/^#ifdef\s+(\w+)/)  {
  275.         push(@printstack,$printit) ;
  276.         if ($defs{$1}) { push(@ifstack,0) ; }
  277.                   else { push(@ifstack,$printit) ; $printit = 0 ; }
  278.         }
  279.      elsif (/^#else/)  {
  280.         $printit =  pop(@ifstack) ;
  281.         push(@ifstack,0) ; 
  282.         }
  283.      elsif (/^#endif/)  {
  284.         $printit = pop(@printstack) ;
  285.         pop(@ifstack) ; 
  286.         }
  287.      elsif (/^# [0-9]/) {
  288.         next ;
  289.         }
  290.      elsif (/^[ \t]*$/) {
  291.         next ;
  292.         }
  293.      elsif (/^<><>/) {
  294.         next ;
  295.         }
  296.      elsif ($printit) {
  297.         print STDOUT ;
  298.         }
  299.     }
  300. }
  301.  
  302. exit;
  303.  
  304. sub Die {
  305.     die $_[0];
  306. }
  307. sub tab {
  308.     "\t" x ($indent / 8) . ' ' x ($indent % 8);
  309. }
  310. sub make_filehandle {
  311.     local($_) = $_[0];
  312.     local($fname) = $_;
  313.     if (!$seen{$fname}) {
  314.     $_ = "FH_" . $_ if /^\d/;
  315.     s/[^a-zA-Z0-9]/_/g;
  316.     s/^_*//;
  317.     $_ = "\U$_";
  318.     if ($fhseen{$_}) {
  319.         for ($tmp = "a"; $fhseen{"$_$tmp"}; $a++) {}
  320.         $_ .= $tmp;
  321.     }
  322.     $fhseen{$_} = 1;
  323.     $opens .= &q(<<"EOT");
  324. :    open($_, '>$fname') || die "Can't create $fname: \$!";
  325. EOT
  326.     $seen{$fname} = $_;
  327.     }
  328.     $seen{$fname};
  329. }
  330.  
  331. sub make_label {
  332.     local($label) = @_;
  333.     $label =~ s/[^a-zA-Z0-9]/_/g;
  334.     if ($label =~ /^[0-9_]/) { $label = 'L' . $label; }
  335.     $label = substr($label,0,8);
  336.  
  337.     # Could be a reserved word, so capitalize it.
  338.     substr($label,0,1) =~ y/a-z/A-Z/
  339.       if $label =~ /^[a-z]/;
  340.  
  341.     $label;
  342. }
  343.  
  344. sub transmogrify {
  345.     {    # case
  346.     if (/^d/) {
  347.         $dseen++;
  348.         chop($_ = &q(<<'EOT'));
  349. :    <<--#ifdef PRINTIT
  350. :    $printit = 0;
  351. :    <<--#endif
  352. :    next LINE;
  353. EOT
  354.         $sawnext++;
  355.         next;
  356.     }
  357.  
  358.     if (/^n/) {
  359.         chop($_ = &q(<<'EOT'));
  360. :    <<--#ifdef PRINTIT
  361. :    <<--#ifdef DSEEN
  362. :    <<--#ifdef ASSUMEP
  363. :    print if $printit++;
  364. :    <<--#else
  365. :    if ($printit)
  366. :        { print; }
  367. :    else
  368. :        { $printit++ unless $nflag; }
  369. :    <<--#endif
  370. :    <<--#else
  371. :    print if $printit;
  372. :    <<--#endif
  373. :    <<--#else
  374. :    print;
  375. :    <<--#endif
  376. :    <<--#ifdef APPENDSEEN
  377. :    if ($atext) {chop $atext; print $atext; $atext = '';}
  378. :    <<--#endif
  379. :    $_ = <>;
  380. :    chop;
  381. :    <<--#ifdef TSEEN
  382. :    $tflag = 0;
  383. :    <<--#endif
  384. EOT
  385.         next;
  386.     }
  387.  
  388.     if (/^a/) {
  389.         $appendseen++;
  390.         $command = $space . "\$atext .= <<'End_Of_Text';\n<<--";
  391.         $lastline = 0;
  392.         while (<>) {
  393.         s/^[ \t]*//;
  394.         s/^[\\]//;
  395.         unless (s|\\$||) { $lastline = 1;}
  396.         s/^([ \t]*\n)/<><>$1/;
  397.         $command .= $_;
  398.         $command .= '<<--';
  399.         last if $lastline;
  400.         }
  401.         $_ = $command . "End_Of_Text";
  402.         last;
  403.     }
  404.  
  405.     if (/^[ic]/) {
  406.         if (/^c/) { $change = 1; }
  407.         $addr1 = 1 if $addr1 eq '';
  408.         $addr1 = '$iter = (' . $addr1 . ')';
  409.         $command = $space .
  410.           "    if (\$iter == 1) { print <<'End_Of_Text'; }\n<<--";
  411.         $lastline = 0;
  412.         while (<>) {
  413.         s/^[ \t]*//;
  414.         s/^[\\]//;
  415.         unless (s/\\$//) { $lastline = 1;}
  416.         s/'/\\'/g;
  417.         s/^([ \t]*\n)/<><>$1/;
  418.         $command .= $_;
  419.         $command .= '<<--';
  420.         last if $lastline;
  421.         }
  422.         $_ = $command . "End_Of_Text";
  423.         if ($change) {
  424.         $dseen++;
  425.         $change = "$_\n";
  426.         chop($_ = &q(<<"EOT"));
  427. :    <<--#ifdef PRINTIT
  428. :    $space\$printit = 0;
  429. :    <<--#endif
  430. :    ${space}next LINE;
  431. EOT
  432.         $sawnext++;
  433.         }
  434.         last;
  435.     }
  436.  
  437.     if (/^s/) {
  438.         $delim = substr($_,1,1);
  439.         $len = length($_);
  440.         $repl = $end = 0;
  441.         $inbracket = 0;
  442.         for ($i = 2; $i < $len; $i++) {
  443.         $c = substr($_,$i,1);
  444.         if ($c eq $delim) {
  445.             if ($inbracket) {
  446.             substr($_, $i, 0) = '\\';
  447.             $i++;
  448.             $len++;
  449.             }
  450.             else {
  451.             if ($repl) {
  452.                 $end = $i;
  453.                 last;
  454.             } else {
  455.                 $repl = $i;
  456.             }
  457.             }
  458.         }
  459.         elsif ($c eq '\\') {
  460.             $i++;
  461.             if ($i >= $len) {
  462.             $_ .= 'n';
  463.             $_ .= <>;
  464.             $len = length($_);
  465.             $_ = substr($_,0,--$len);
  466.             }
  467.             elsif (substr($_,$i,1) =~ /^[n]$/) {
  468.             ;
  469.             }
  470.             elsif (!$repl &&
  471.               substr($_,$i,1) =~ /^[(){}\w]$/) {
  472.             $i--;
  473.             $len--;
  474.             substr($_, $i, 1) = '';
  475.             }
  476.             elsif (!$repl &&
  477.               substr($_,$i,1) =~ /^[<>]$/) {
  478.             substr($_,$i,1) = 'b';
  479.             }
  480.         }
  481.         elsif ($c eq '[' && !$repl) {
  482.             $i++ if substr($_,$i,1) eq '^';
  483.             $i++ if substr($_,$i,1) eq ']';
  484.             $inbracket = 1;
  485.         }
  486.         elsif ($c eq ']') {
  487.             $inbracket = 0;
  488.         }
  489.         elsif ($c eq "\t") {
  490.             substr($_, $i, 1) = '\\t';
  491.             $i++;
  492.             $len++;
  493.         }
  494.         elsif (!$repl && index("()+",$c) >= 0) {
  495.             substr($_, $i, 0) = '\\';
  496.             $i++;
  497.             $len++;
  498.         }
  499.         }
  500.         &Die("Malformed substitution at line $.\n")
  501.           unless $end;
  502.         $pat = substr($_, 0, $repl + 1);
  503.         $repl = substr($_, $repl+1, $end-$repl-1);
  504.         $end = substr($_, $end + 1, 1000);
  505.         &simplify($pat);
  506.         $dol = '$';
  507.         $repl =~ s/\$/\\$/;
  508.         $repl =~ s'&'$&'g;
  509.         $repl =~ s/[\\]([0-9])/$dol$1/g;
  510.         $subst = "$pat$repl$delim";
  511.         $cmd = '';
  512.         while ($end) {
  513.         if ($end =~ s/^g//) {
  514.             $subst .= 'g';
  515.             next;
  516.         }
  517.         if ($end =~ s/^p//) {
  518.             $cmd .= ' && (print)';
  519.             next;
  520.         }
  521.         if ($end =~ s/^w[ \t]*//) {
  522.             $fh = &make_filehandle($end);
  523.             $cmd .= " && (print $fh \$_)";
  524.             $end = '';
  525.             next;
  526.         }
  527.         &Die("Unrecognized substitution command".
  528.           "($end) at line $.\n");
  529.         }
  530.         chop ($_ = &q(<<"EOT"));
  531. :    <<--#ifdef TSEEN
  532. :    $subst && \$tflag++$cmd;
  533. :    <<--#else
  534. :    $subst$cmd;
  535. :    <<--#endif
  536. EOT
  537.         next;
  538.     }
  539.  
  540.     if (/^p/) {
  541.         $_ = 'print;';
  542.         next;
  543.     }
  544.  
  545.     if (/^w/) {
  546.         s/^w[ \t]*//;
  547.         $fh = &make_filehandle($_);
  548.         $_ = "print $fh \$_;";
  549.         next;
  550.     }
  551.  
  552.     if (/^r/) {
  553.         $appendseen++;
  554.         s/^r[ \t]*//;
  555.         $file = $_;
  556.         $_ = "\$atext .= `cat $file 2>/dev/null`;";
  557.         next;
  558.     }
  559.  
  560.     if (/^P/) {
  561.         $_ = 'print $1 if /^(.*)/;';
  562.         next;
  563.     }
  564.  
  565.     if (/^D/) {
  566.         chop($_ = &q(<<'EOT'));
  567. :    s/^.*\n?//;
  568. :    redo LINE if $_;
  569. :    next LINE;
  570. EOT
  571.         $sawnext++;
  572.         next;
  573.     }
  574.  
  575.     if (/^N/) {
  576.         chop($_ = &q(<<'EOT'));
  577. :    $_ .= "\n";
  578. :    $len1 = length;
  579. :    $_ .= <>;
  580. :    chop if $len1 < length;
  581. :    <<--#ifdef TSEEN
  582. :    $tflag = 0;
  583. :    <<--#endif
  584. EOT
  585.         next;
  586.     }
  587.  
  588.     if (/^h/) {
  589.         $_ = '$hold = $_;';
  590.         next;
  591.     }
  592.  
  593.     if (/^H/) {
  594.         $_ = '$hold .= "\n"; $hold .= $_;';
  595.         next;
  596.     }
  597.  
  598.     if (/^g/) {
  599.         $_ = '$_ = $hold;';
  600.         next;
  601.     }
  602.  
  603.     if (/^G/) {
  604.         $_ = '$_ .= "\n"; $_ .= $hold;';
  605.         next;
  606.     }
  607.  
  608.     if (/^x/) {
  609.         $_ = '($_, $hold) = ($hold, $_);';
  610.         next;
  611.     }
  612.  
  613.     if (/^b$/) {
  614.         $_ = 'next LINE;';
  615.         $sawnext++;
  616.         next;
  617.     }
  618.  
  619.     if (/^b/) {
  620.         s/^b[ \t]*//;
  621.         $lab = &make_label($_);
  622.         if ($lab eq $toplabel) {
  623.         $_ = 'redo LINE;';
  624.         } else {
  625.         $_ = "goto $lab;";
  626.         }
  627.         next;
  628.     }
  629.  
  630.     if (/^t$/) {
  631.         $_ = 'next LINE if $tflag;';
  632.         $sawnext++;
  633.         $tseen++;
  634.         next;
  635.     }
  636.  
  637.     if (/^t/) {
  638.         s/^t[ \t]*//;
  639.         $lab = &make_label($_);
  640.         $_ = q/if ($tflag) {$tflag = 0; /;
  641.         if ($lab eq $toplabel) {
  642.         $_ .= 'redo LINE;}';
  643.         } else {
  644.         $_ .= "goto $lab;}";
  645.         }
  646.         $tseen++;
  647.         next;
  648.     }
  649.  
  650.     if (/^y/) {
  651.         s/abcdefghijklmnopqrstuvwxyz/a-z/g;
  652.         s/ABCDEFGHIJKLMNOPQRSTUVWXYZ/A-Z/g;
  653.         s/abcdef/a-f/g;
  654.         s/ABCDEF/A-F/g;
  655.         s/0123456789/0-9/g;
  656.         s/01234567/0-7/g;
  657.         $_ .= ';';
  658.     }
  659.  
  660.     if (/^=/) {
  661.         $_ = 'print $.;';
  662.         next;
  663.     }
  664.  
  665.     if (/^q/) {
  666.         chop($_ = &q(<<'EOT'));
  667. :    close(ARGV);
  668. :    @ARGV = ();
  669. :    next LINE;
  670. EOT
  671.         $sawnext++;
  672.         next;
  673.     }
  674.     } continue {
  675.     if ($space) {
  676.         s/^/$space/;
  677.         s/(\n)(.)/$1$space$2/g;
  678.     }
  679.     last;
  680.     }
  681.     $_;
  682. }
  683.  
  684. sub fetchpat {
  685.     local($outer) = @_;
  686.     local($addr) = $outer;
  687.     local($inbracket);
  688.     local($prefix,$delim,$ch);
  689.  
  690.     # Process pattern one potential delimiter at a time.
  691.  
  692.     DELIM: while (s#^([^\]+(|)[\\/]*)([]+(|)[\\/])##) {
  693.     $prefix = $1;
  694.     $delim = $2;
  695.     if ($delim eq '\\') {
  696.         s/(.)//;
  697.         $ch = $1;
  698.         $delim = '' if $ch =~ /^[(){}A-Za-mo-z]$/;
  699.         $ch = 'b' if $ch =~ /^[<>]$/;
  700.         $delim .= $ch;
  701.     }
  702.     elsif ($delim eq '[') {
  703.         $inbracket = 1;
  704.         s/^\^// && ($delim .= '^');
  705.         s/^]// && ($delim .= ']');
  706.     }
  707.     elsif ($delim eq ']') {
  708.         $inbracket = 0;
  709.     }
  710.     elsif ($inbracket || $delim ne $outer) {
  711.         $delim = '\\' . $delim;
  712.     }
  713.     $addr .= $prefix;
  714.     $addr .= $delim;
  715.     if ($delim eq $outer && !$inbracket) {
  716.         last DELIM;
  717.     }
  718.     }
  719.     $addr =~ s/\t/\\t/g;
  720.     &simplify($addr);
  721.     $addr;
  722. }
  723.  
  724. sub q {
  725.     local($string) = @_;
  726.     local($*) = 1;
  727.     $string =~ s/^:\t?//g;
  728.     $string;
  729. }
  730.  
  731. sub simplify {
  732.     $_[0] =~ s/_a-za-z0-9/\\w/ig;
  733.     $_[0] =~ s/a-z_a-z0-9/\\w/ig;
  734.     $_[0] =~ s/a-za-z_0-9/\\w/ig;
  735.     $_[0] =~ s/a-za-z0-9_/\\w/ig;
  736.     $_[0] =~ s/_0-9a-za-z/\\w/ig;
  737.     $_[0] =~ s/0-9_a-za-z/\\w/ig;
  738.     $_[0] =~ s/0-9a-z_a-z/\\w/ig;
  739.     $_[0] =~ s/0-9a-za-z_/\\w/ig;
  740.     $_[0] =~ s/\[\\w\]/\\w/g;
  741.     $_[0] =~ s/\[^\\w\]/\\W/g;
  742.     $_[0] =~ s/\[0-9\]/\\d/g;
  743.     $_[0] =~ s/\[^0-9\]/\\D/g;
  744.     $_[0] =~ s/\\d\\d\*/\\d+/g;
  745.     $_[0] =~ s/\\D\\D\*/\\D+/g;
  746.     $_[0] =~ s/\\w\\w\*/\\w+/g;
  747.     $_[0] =~ s/\\t\\t\*/\\t+/g;
  748.     $_[0] =~ s/(\[.[^]]*\])\1\*/$1+/g;
  749.     $_[0] =~ s/([\w\s!@#%^&-=,:;'"])\1\*/$1+/g;
  750. }
  751.  
  752.